package com.gin.kotlin.no_gay_alliance.fragment.replyhistory

import android.content.res.Configuration
import android.os.Bundle
import android.view.ViewGroup
import android.webkit.JavascriptInterface
import androidx.annotation.DrawableRes
import androidx.core.graphics.drawable.toBitmap
import com.gin.kotlin.no_gay_alliance.R
import com.gin.kotlin.no_gay_alliance.activity.replyhistory.ReplyHistoryActivity
import com.gin.kotlin.no_gay_alliance.activity.ReplyListActivity
import com.gin.kotlin.no_gay_alliance.activity.UserCenterActivity
import com.gin.kotlin.no_gay_alliance.app.App
import com.gin.kotlin.no_gay_alliance.argument.ReplyHistoryArgument
import com.gin.kotlin.no_gay_alliance.argument.ReplyListArgument
import com.gin.kotlin.no_gay_alliance.base.PhotoPreviewUtils
import com.gin.kotlin.no_gay_alliance.database.entity.ReplyHistory
import com.gin.kotlin.no_gay_alliance.databinding.FragmentReplyHistoryPageBinding
import com.gin.kotlin.no_gay_alliance.enums.NgaTheme
import com.gin.kotlin.no_gay_alliance.fragment.replylist.ReplyPageHtmlFragment.Companion.bitmapToBase64
import com.gin.kotlin.no_gay_alliance.listener.PhotoPreviewLongClickListener
import com.gin.kotlin.no_gay_alliance.store.GlobalProperty
import com.gin.kotlin.no_gay_alliance.utils.TimeUtils
import com.gin.kotlin.no_gay_alliance.webview.BbsCodeWebView
import com.gin.nga.enums.ImageThumb
import com.gin.nga.utils.BbsCodeRenderer
import com.gin.nga.utils.StrUtils

/**
 * 使用HTML渲染的回复历史Fragment
 */
class ReplyHistoryPageHtmlFragment : AbstractReplyHistoryPageFragment() {
    private lateinit var data: List<ReplyHistory>
    private lateinit var renderer: BbsCodeRenderer
    private lateinit var replyTemplate: String
    private lateinit var template: String
    private lateinit var webView: BbsCodeWebView
    override fun initRenderComponent(b: FragmentReplyHistoryPageBinding) {
        val activity = requireActivity() as? ReplyHistoryActivity ?: return
        this.webView = activity.bbsCodeWebViewPool.obtainWebView()
            .also {
                it.layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
                // 点击事件
                it.addJavascriptInterface(this, "android")
            }
        b.swipeRefreshLayout.addView(this.webView)
        b.swipeRefreshLayout.setOnRefreshListener { activity.refresh() }

        // 加载模板和渲染器
        this.template = requireContext().assets.open("template.html").bufferedReader().readText()
        this.replyTemplate = requireContext().assets.open("reply_history_template.html").bufferedReader().readText()
        this.renderer = BbsCodeRenderer(GlobalProperty.getInstance().domain, App.INSTANCE.emoteGroup)
    }

    override fun render(data: List<ReplyHistory>) {
        val globalProperty = GlobalProperty.getInstance()
        // 系统当前是否处于深色模式
        val systemUiModeNight = resources.configuration.uiMode.and(Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES
        // 系统当前主题
        val theme = if (systemUiModeNight && globalProperty.themeFollow) NgaTheme.BLACK else globalProperty.theme

        val rootClass = ""
        this.data = data
        val containers = renderReplies(data, theme)

        val html = template.replace("[根CLASS占位]", rootClass).replace("[回复容器占位]", containers)

        this.webView.loadDataWithBaseURL(html)

    }

    /**
     * 渲染回复历史，支持的功能：
     * * 打开原帖
     * * 打开主题
     * * 打开用户中心
     * * 显示记录时间
     * @param replyHistories List<ReplyHistory>
     * @param theme NgaTheme
     * @return String
     */
    private fun renderReplies(replyHistories: List<ReplyHistory>, theme: NgaTheme): String {

        return replyHistories.withIndex().joinToString("") { indexedValue ->
            val index = indexedValue.index
            val dataModel = indexedValue.value

            // 斑马模式 亮色
            val light = index % 2 == 0

            // 背景颜色
            val bgcClass = when (theme) {
                NgaTheme.YELLOW -> if (light) "background_color_yellow_light" else "background_color_yellow_dark"
                NgaTheme.GREEN -> if (light) "background_color_green_light" else "background_color_green_dark"
                NgaTheme.BLACK -> if (light) "background_color_black_light" else "background_color_black_dark"
            }

            // 容器class
            val containerClass = if (theme == NgaTheme.BLACK) "black_text_color" else "default_text_color"
            // 正文字体颜色
            val contentClass = if (theme == NgaTheme.BLACK) "black_text_color" else "default_text_color"
            // 头像
            val avatar = if (dataModel.anonymous)
                obtainImgByDrawableId(R.drawable.ic_person_anonymous_16) ?: ""
            else
                obtainImgByDrawableId(R.drawable.ic_person_18) ?: ""

            replyTemplate
                .replace("{容器CLASS占位}", containerClass)
                .replace("{背景色CLASS占位}", bgcClass)
                .replace("{replyId}", dataModel.replyId.toString())
                .replace("{topicId}", dataModel.topicId.toString())
                .replace("{标题占位}", StrUtils.escape(dataModel.title) ?: "")
                .replace("{主题标题占位}", StrUtils.escape(dataModel.topicTitle) ?: "")
                .replace("{修改时间占位}", TimeUtils.FULL_DATE_TIME_FORMATTER.format(dataModel.lastEdit))
                .replace("{发布时间占位}", TimeUtils.FULL_DATE_TIME_FORMATTER.format(dataModel.postDateTime))
                .replace("{记录时间占位}", TimeUtils.FULL_DATE_TIME_FORMATTER.format(dataModel.timestamp))
                .replace("{centerUserId}", dataModel.authorUid.toString())
                .replace("{正文占位}", renderer.render(dataModel.getBbsCodeNode()))
                .replace("{正文CLASS}", contentClass)
                .replace("{用户名占位}", dataModel.username)
                .replace("{头像占位}", avatar)
                .replace("{楼层占位}", "${dataModel.floorNumber}楼")
        }
    }

    /**
     * 将drawable转换为base64
     * @param drawableId Int
     * @return String?
     */
    private fun obtainImgByDrawableId(@DrawableRes drawableId: Int) = getDrawable(drawableId)?.toBitmap()?.let { "data:image/png;base64,${bitmapToBase64(it)}" }

    /**
     *  打开主题
     * @param topicId Long
     */
    @JavascriptInterface
    fun openTopic(topicId: Long) = ReplyListActivity.startActivity(requireContext(), ReplyListArgument(ReplyListArgument.Type.LIST, topicId = topicId))

    /**
     *  打开回复
     * @param replyId Long
     */
    @JavascriptInterface
    fun openReply(replyId: Long, topicId: Long) = if (replyId > 0)
        ReplyListActivity.startActivity(requireContext(), ReplyListArgument(ReplyListArgument.Type.SINGLE, replyId = replyId))
    else
        openTopic(topicId)

    /**
     *  打开用户中心
     * @param userId Long
     */
    @JavascriptInterface
    fun openUserCenter(userId: Long) = UserCenterActivity.startActivity(requireContext(), userId)

    /**
     * 预览指定url的图片
     * @param url String
     */
    @JavascriptInterface
    fun previewByUrl(url: String) {
        // 打开预览的界面(缩略图所处界面)，预览生命周期与activity绑定
        var u = url

        // 移除缩略图后缀
        ImageThumb.entries.forEach {
            if (u.endsWith(it.suffix)) u = u.replace(it.suffix, "")
        }

        App.INSTANCE.handler?.post {
            PhotoPreviewUtils.build(requireActivity(), listOf(u), listener = PhotoPreviewLongClickListener(requireActivity()) { _ ->
                run {
                    // 检查链接形式，如果是附件格式转换为code
                    val code = if (u.startsWith(ImageThumb.PREFIX)) u.replace(ImageThumb.PREFIX, "").let { "[img]./$it[/img]" } else ""
                    PhotoPreviewLongClickListener.PreviewImage(u, code)
                }
            }).build().show()
        }
    }


    override fun onDestroyView() {
        super.onDestroyView()

        (this.webView.parent as? ViewGroup)?.removeAllViews()
        this.webView.busy = false
        this.webView.loadDataWithBaseURL("")
    }

    companion object {
        fun newInstance(argument: ReplyHistoryArgument): ReplyHistoryPageHtmlFragment {
            val args = Bundle()
            args.putParcelable(ReplyHistoryArgument::class.java.simpleName, argument)
            val fragment = ReplyHistoryPageHtmlFragment()
            fragment.arguments = args
            return fragment
        }
    }
}